import json
import os

from fastapi import APIRouter, UploadFile, Depends, Form
from fastapi.encoders import jsonable_encoder
from pydantic import BaseModel
from sqlalchemy.orm import Session
from starlette import status
from starlette.responses import JSONResponse, FileResponse

from api.database.curd import create_standrad_lib, standrad_lib_list, standrad_lib_get
from api.database.database import get_db
from api.database.models import StandradLibEntity
from api.utils import rootpath

router = APIRouter()


class StandradLibItem(BaseModel):
    user_name: str | None = None
    name: str
    desc: str


@router.post("/upload")
async def upload_file(file: UploadFile, item: str = Form(), db: Session = Depends(get_db)):
    item_json = json.loads(item)
    stand_item = StandradLibItem(**item_json)

    file_path = rootpath() + "\\data\\standrad\\" + file.filename
    context = await file.read()
    with open(file_path, "wb") as buffer:
        buffer.write(context)

    releave_path = os.path.relpath(file_path, rootpath())

    # 写完文件更新数据库;
    stand_entity = StandradLibEntity(**stand_item.dict())
    stand_entity.path = releave_path
    create_standrad_lib(db, stand_entity)
    return JSONResponse(content={"message": "ok"}, status_code=status.HTTP_200_OK)


# 获取所有的标准库列表
@router.get('/list')
async def standrad_list_post(db: Session = Depends(get_db)):
    standrad_entity_list = standrad_lib_list(db)
    if not standrad_entity_list:
        return JSONResponse(content={"message": ""}, status_code=status.HTTP_200_OK)
    items_json = jsonable_encoder(standrad_entity_list)
    return JSONResponse(content={"message": json.dumps(items_json)}, status_code=status.HTTP_200_OK)


@router.get('/download')
async def download_file(standrad_name: str, db: Session = Depends(get_db)):
    standrad_entity = standrad_lib_get(db, standrad_name)
    if not standrad_entity:
        return JSONResponse(content={"message": "未找到标准库文件"}, status_code=status.HTTP_400_BAD_REQUEST)

    file_path = os.path.join(rootpath(), standrad_entity.path)
    # 使用FileResponse发送文件
    return FileResponse(file_path, media_type="application/octet-stream", filename=standrad_name)
